import React, {
    useRef,
    useState,
    forwardRef,
    useMemo,
    useImperativeHandle,
    useEffect,
    useContext,
    useCallback
} from 'react';

import { Form, Modal, Button, Icon, Message, Tooltip } from 'antd';
import { NumberInput } from '@/pages/SalaryManage/components/NumberInput';
import { getRandomIndex } from '@/pages/SalaryManage/utils';
import { EmployeeSelector, useFetchEmployeeData } from '@/components/OrgSelector';
import { BaseSettingContext } from '@/pages/SalaryManage/constant/BaseSettingContext';
import styles from './index.less';

const getOrgListByCode = (orgList = [], pId, currentOrgList) => {
    const organizationList = {};
    // 过滤出人的
    if (!pId) {
        orgList.forEach(org => {
            if (org.employeeCode) {
                organizationList[org.employeeCode] = getOrgListByCode(orgList, org.pId, []);
            }
        });
        return organizationList;
    }
    if (pId && currentOrgList) {
        const parentOrg = orgList.find(org => org.id === pId) || {};
        // 拿到两级的机构，用于展示倒数第二级
        if (parentOrg.pId) {
            return getOrgListByCode(orgList, parentOrg.pId, [...currentOrgList, parentOrg]);
        }
        return [...currentOrgList];
    }
    return [];
};

const getColumns = (form, showAmount, updateAmount, decimalPlaces) => {
    const { getFieldDecorator } = form;
    const baseColumns = [
        {
            key: 'no',
            index: 'no',
            title: '序号',
            width: '71px'
        },
        {
            key: 'employeeNo',
            index: 'employeeCode',
            title: '工号',
            width: '117px'
        },
        {
            key: 'employeeName',
            index: 'employeeName',
            title: '姓名',
            width: '145px'
        },
        {
            key: 'departmentName',
            index: 'departmentName',
            title: '组织机构',
            width: '218px',
            render: row => (
                <div className={styles.departmentName}>
                    <span>{row.departmentName}</span>
                    <span>
                        <Tooltip title={row.departmentFullName}>
                            <Icon type="info-circle" style={{ color: '#ffb957' }} />
                        </Tooltip>
                    </span>
                </div>
            )
        }
    ];
    if (!showAmount) return baseColumns;
    return [
        ...baseColumns,
        {
            key: 'specialAmt',
            index: 'specialAmt',
            title: '金额($)',
            width: '196px',
            render: (row, index) => (
                <Form.Item style={{ marginRight: '14px' }}>
                    {getFieldDecorator(`specialAmt_${row.index}`, {
                        initialValue: row.specialAmt,
                        rules: [{ required: true, message: '请输入金额' }]
                    })(
                        <NumberInput
                            onChange={value => updateAmount(index, value)}
                            disabled={row.disabled}
                            placeholder="请输入金额"
                            thousandsSeparator=","
                            maxLength={15}
                            decimalPlaces={decimalPlaces}
                        />
                    )}
                </Form.Item>
            )
        }
    ];
};
const filterFields = ['employeeCode', 'id', 'salaryItemId', 'specialAmt', 'employeeNo'];
const filterNoAmtFields = ['employeeCode', 'id', 'salaryItemId', 'employeeNo'];

const SelectedStaffEdit = forwardRef((props, ref) => {
    const {
        list,
        showAmount = false,
        form,
        isAllMode,
        isFilterField = false,
        readonly,
        visibleStaffSelect,
        organizationCode
    } = props;
    const employeeSelectorRef = useRef(null);
    const [showAllStaff, setShowAllStaff] = useState(false);
    const [initedSelectStaff, setInitedSelectStaff] = useState(true);
    const [dataSource, setDataSource] = useState(
        (list || []).map(item => ({
            ...item,
            index: getRandomIndex()
        }))
    );
    //
    // 生成code为key的数据map
    const amtInfoById = useMemo(() => {
        const obj = {};
        dataSource.forEach(data => {
            obj[data.employeeCode] = data;
        });
        return obj;
    }, [dataSource]);
    const {
        baseSetting: { scale: decimalPlaces }
    } = useContext(BaseSettingContext);
    // 外部获取人员所在的机构信息
    const { data: employeeData = [] } = useFetchEmployeeData({
        param: { administrativeOrganizationCode: organizationCode }
    });

    const orgListByCode = useMemo(() => getOrgListByCode(employeeData), [employeeData]);
    // 更新金额数据
    const updateAmount = (index, amt) => {
        setDataSource(
            dataSource.map(data => {
                if (data.index === index) {
                    return {
                        ...data,
                        specialAmt: amt
                    };
                }
                return { ...data };
            })
        );
    };
    // 人员选择器默认值
    const usersCode = useMemo(() => dataSource.map(data => data.employeeCode), [dataSource]);

    // 打开人员选择弹窗
    const openEmployeeSelector = useCallback(() => {
        if (employeeSelectorRef && employeeSelectorRef.current) {
            employeeSelectorRef.current.open(usersCode);
        }
    });
    // 关闭人员选择弹窗
    const closeEmployeeSelector = useCallback(() => {
        employeeSelectorRef.current.close();
    });

    // 点击初始化弹窗
    useEffect(() => {
        if (!initedSelectStaff && !readonly) {
            openEmployeeSelector();
            setInitedSelectStaff(true);
        }
    }, [initedSelectStaff]);

    // 外部人员数据改变
    useEffect(() => {
        setDataSource(
            (list || []).map(item => {
                const orgList = orgListByCode[item.employeeCode] || [
                    { ...item, organizationName: item.organizationName }
                ];
                const departNameList = orgList.map(org => org.organizationName).reverse();

                return {
                    ...item,
                    departmentName: departNameList[departNameList.length - 1],
                    departmentFullName: departNameList.join('/'),
                    index: getRandomIndex()
                };
            })
        );
    }, [list, orgListByCode]);

    // 根据visibleStaffSelect变化判断是否要初始化弹窗
    useEffect(() => {
        if (visibleStaffSelect && !usersCode.length) {
            setInitedSelectStaff(false);
        }
    }, [visibleStaffSelect]);

    // 获取当前显示的列
    const columns = useMemo(() => getColumns(form, showAmount, updateAmount, decimalPlaces), [
        showAmount,
        form,
        decimalPlaces,
        dataSource
    ]);

    // 点击全部人员
    const triggerAllStaff = bool => setShowAllStaff(typeof bool === 'undefined' ? bool : !showAllStaff);

    // 获取最小宽度，用于处理formItem不够长问题
    const minWidth = columns.reduce((pre, next) => pre + parseInt(next.width, 10), 0);

    // 点击全部人员确定按钮
    const onOk = dataList => {
        setDataSource([...dataList]);
        triggerAllStaff(true);
    };

    // 删除某条数据
    const handleDelete = index => {
        setDataSource(dataSource.filter(data => data.index !== index));
    };

    // 选择人员弹窗
    const onChangeSelectStaff = (userIds, users) => {
        // const restUsers = users.filter(user => dataSource.find(data => data.employeeCode !== user.employeeCode));
        const newUserItems = users.map(user => {
            if (amtInfoById[user.employeeCode]) {
                return amtInfoById[user.employeeCode];
            }
            // 当前员工所在机构list
            const orgList = orgListByCode[user.employeeCode] || [user];
            // 拿出后面两级
            const departNameList = orgList.map(org => org.organizationName).reverse();

            return {
                employeeNo: user.userNo,
                employeeCode: user.employeeCode,
                departmentName: departNameList[departNameList.length - 1],
                departmentFullName: departNameList.join('/'),
                employeeName: user.employeeName,
                index: getRandomIndex()
            };
        });
        setDataSource([...newUserItems]);
        closeEmployeeSelector();
    };

    useImperativeHandle(
        ref,
        () => ({
            openEmployeeSelectorRef: () => {
                openEmployeeSelector();
            },
            getData: () =>
                new Promise((resolve, reject) => {
                    form.validateFields(err => {
                        // 判断展示金额的情况下，超过三个以上没有填写显示message
                        const requiredErr =
                            (showAmount &&
                                !isAllMode &&
                                !!dataSource.find((data, index) => index > 2 && !data.specialAmt)) ||
                            false;
                        if (!err && !requiredErr) {
                            // 是否获取全部的字段，如果不是走过滤字段
                            if (!isFilterField) {
                                resolve(dataSource);
                            } else {
                                resolve(
                                    dataSource.map(item => {
                                        const newItem = {};
                                        const fields = showAmount ? filterFields : filterNoAmtFields;
                                        Object.keys(item).forEach(key => {
                                            if (fields.indexOf(key) > -1) {
                                                newItem[key] = item[key];
                                            }
                                        });
                                        return newItem;
                                    })
                                );
                            }
                        } else if (requiredErr) {
                            Message.error('存在特殊金额为空，请打开全部进行填写！');
                        } else {
                            console.log(err, 111);
                            reject(err);
                        }
                    });
                })
        }),
        [dataSource, showAmount, usersCode]
    );

    if (!visibleStaffSelect && !isAllMode) {
        return null;
    }

    const getIsScroll = () => (isAllMode && dataSource.length > 7) || (!isAllMode && dataSource.length > 3) || false;

    return (
        <div>
            <div
                className={`${styles.listWrapper} ${isAllMode ? styles.tableWrapper : ''} ${
                    readonly ? styles.readonly : ''
                }`}
                style={{ width: `${minWidth}px` }}
            >
                <HeaderLine columns={columns} style={{ paddingRight: getIsScroll() ? '6px' : 0 }} />
                {dataSource.length ? (
                    <BodyWrapper
                        columns={columns}
                        dataSource={dataSource}
                        // dataSource={isAllMode ? dataSource : dataSource.slice(0, 3)}
                        handleDelete={handleDelete}
                        isAllMode={isAllMode}
                        disabled={readonly}
                        scroll={{ y: isAllMode ? 378 : 162 }}
                    />
                ) : (
                    <div className={styles.empty}>暂无数据</div>
                )}
                {(!isAllMode && (
                    <Footer
                        showSelectStaff={openEmployeeSelector}
                        showAllStaff={triggerAllStaff}
                        showAmount={showAmount}
                        readonly={readonly}
                    />
                )) ||
                    null}
            </div>
            {(showAllStaff && (
                <AllStaffModal
                    onOk={onOk}
                    onCancel={triggerAllStaff}
                    showAmount={showAmount}
                    dataSource={dataSource}
                    width={minWidth}
                    readonly={readonly}
                    organizationCode={organizationCode}
                />
            )) ||
                null}
            <div>
                <EmployeeSelector
                    modal
                    manual
                    multiple
                    ref={employeeSelectorRef}
                    onChange={onChangeSelectStaff}
                    data={employeeData}
                />
            </div>
        </div>
    );
});
// 头部
const HeaderLine = props => (
    <ul className={`${styles.tableHeader} ${styles.headerLine} ${styles.line}`} style={{ ...(props.style || {}) }}>
        {props.columns.map(col => (
            <li style={{ width: col.width ? col.width : 'auto' }}>
                <span className={styles.headerLineItem}>{col.title}</span>
            </li>
        ))}
    </ul>
);
// 中间部分
const BodyWrapper = props => {
    const { dataSource = [], columns, disabled, scroll, isScroll, ...restProps } = props;
    const bodyStyle = {};
    if (scroll.y) {
        bodyStyle.maxHeight = `${scroll.y}px`;
        bodyStyle.overflowY = 'auto';
    }

    return (
        <ul className={styles.tableBody} style={{ ...bodyStyle }}>
            {dataSource.map((data, no) => (
                <BodyLine data={{ ...data, no: no + 1, disabled }} key={data.index} columns={columns} {...restProps} />
            ))}
        </ul>
    );
};
// 中间行
const BodyLine = props => {
    const { columns, data, handleDelete, isAllMode } = props;
    const len = columns.length;

    return (
        <ul className={`${styles.bodyLine} ${styles.line}`}>
            {columns.map((col, index) => (
                <li
                    style={{ width: col.width ? col.width : 'auto' }}
                    className={`${index === len - 1 ? styles.bodyLineLastItem : ''}`}
                >
                    <span className={styles.bodyLineItem} title={data[col.key]}>
                        {(col.render && col.render(data, data.index)) || data[col.key]}
                    </span>
                </li>
            ))}
            {(isAllMode && !data.disabled && (
                <span className={styles.lineCloseIcon} onClick={() => handleDelete(data.index)}>
                    <Icon type="close" />
                </span>
            )) ||
                null}
        </ul>
    );
};

// 尾部
const Footer = props => {
    const { showAmount, showAllStaff, showSelectStaff, readonly } = props;
    return (
        <div className={styles.footer}>
            {showAmount || readonly ? (
                <span onClick={showAllStaff}>{showAmount ? '设置金额' : '显示全部'}</span>
            ) : (
                <span onClick={() => showSelectStaff(true)}>选择人员</span>
            )}
        </div>
    );
};

// 展示全部弹窗
const AllStaffModal = props => {
    const { showAmount = false, onOk, onCancel, dataSource, width, readonly, organizationCode } = props;
    const selectedStallRef = useRef(null);
    // const employeeSelectorRef = useRef(null);

    const handleOk = async () => {
        try {
            const dataList = await selectedStallRef.current.getData();
            onOk(dataList);
        } catch (err) {
            console.log(err, '报错了');
        }
    };

    const handleSelectStaff = () => {
        selectedStallRef.current.openEmployeeSelectorRef();
    };

    let footer = [
        <Button onClick={onCancel}>取消</Button>,
        <Button onClick={handleSelectStaff} type="primary" ghost>
            选择人员
        </Button>,
        <Button onClick={handleOk} type="primary">
            确定
        </Button>
    ];

    if (readonly) {
        footer = null;
    }
    return (
        <div>
            <Modal
                visible
                title="设置金额"
                onCancel={onCancel}
                footer={footer}
                width={width + 24}
                bodyStyle={{ maxHeight: '500px', overflow: 'auto' }}
            >
                <FormToSelectedStaffEdit
                    showAmount={showAmount}
                    list={dataSource}
                    isAllMode
                    wrappedComponentRef={selectedStallRef}
                    readonly={readonly}
                    organizationCode={organizationCode}
                />
            </Modal>
        </div>
    );
};

const FormToSelectedStaffEdit = Form.create()(SelectedStaffEdit);
export default FormToSelectedStaffEdit;
